﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using BLL.Services.Messages.Listing;

namespace BLL.Services.Messages
{
    public class MessagesCollection
    {
        private readonly string _connectionString;

        public MessagesCollection(string connectionString)
        {
            _connectionString = connectionString;
        }

        public Messages SelectById(int messageId)
        {
            Messages result = null;
            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var cmd = StoredProcedures.Message.SelectById(conn, messageId);

                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        result = GetMessage(reader);
                    }
                }
            }
            return result;
        }

        public ListingUserMessage GetListingMessage(int page, int userId, int size, string column, int direction, ListingUserMessageFilter filter)
        {
            if (filter == null)
                filter = new ListingUserMessageFilter();
            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var cmd = StoredProcedures.Message.SelectByUser(conn, userId, page, size, column, direction,filter.Login);
                var totalCount = new SqlParameter("@TotalCount", SqlDbType.Int, 4)
                    {
                        Direction = ParameterDirection.ReturnValue
                    };
                cmd.Parameters.Add(totalCount);

                var result = new ListingUserMessage
                    {
                        Column = column,
                        Direction = direction,
                        Filter = filter,
                        Size = size,
                        Page = page

                    };
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var item = new ListingUserMessage.ListingMessage();
                        if (!string.IsNullOrEmpty(reader[0].ToString()))
                            item.DateOfRead = reader.GetDateTime(0);
                        item.DateOfSend = reader.GetDateTime(1);
                        item.Login = reader[2] as string;
                        item.Avatar = reader[3] as string;
                        item.UserId = reader.GetInt32(4);
                        item.Message = reader[5] as string;

                        result.Messages.Add(item);

                    }
                }

                result.TotalPages = (int)totalCount.Value % size == 0
                                        ? (int)totalCount.Value / size
                                        : ((int)totalCount.Value / size) + 1;
                return result;
            }
        }

        public ListingMessage GetListingUser(int recepientId, int senderId, int page, int size)
        {

            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var cmd = StoredProcedures.Message.GetListing(conn, recepientId, senderId, page, size);
                var totalCount = new SqlParameter("@TotalCount", SqlDbType.Int, 4)
                    {
                        Direction = ParameterDirection.ReturnValue
                    };
                cmd.Parameters.Add(totalCount);

                var result = new ListingMessage
                    {
                        Size = size,
                        Page = page
                    };
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var listing = new ListingMessage.MessageList
                            {
                                Message = reader[0] as string,
                                Email = reader[1] as string,
                                Avatar = reader[2] as string,
                                Login = reader[3] as string
                            };
                        result.Messages.Add(listing);
                    }
                }
                result.TotalPages = (int)totalCount.Value % size == 0 ? (int)totalCount.Value / size : (int)totalCount.Value / size + 1;

                return result;
            }
        }

        

        public IEnumerable<Messages> SelectAll()
        {
            var result = new List<Messages>();
            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var cmd = StoredProcedures.Message.SelectAll(conn);
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        var message = GetMessage(reader);
                        result.Add(message);
                    }
                }
            }
            return result;
        }


        public Messages Create(Messages model)
        {
            model.DateOfSend = DateTime.Now;
            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var cmd = StoredProcedures.Message.Insert(
                    conn, model.DateOfRead, model.DateOfSend, model.Message, model.RecipientId, model.SenderId);
                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        model = GetMessage(reader);
                    }
                }
            }
            return model;
        }

        public void Save(Messages model)
        {
            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var cmd = StoredProcedures.Message.Update(conn, model.MessageId, model.DateOfRead, model.DateOfSend, model.Message, model.RecipientId, model.SenderId);
                cmd.ExecuteNonQuery();
            }
        }

        public void SetNotReadMessage(int senderId, int recipientId, DateTime dateTime)
        {
            using (var conn  = new SqlConnection(_connectionString))
            {
                conn.Open();
                var cmd = StoredProcedures.Message.SetNotRead(conn, senderId, recipientId, dateTime);
                cmd.ExecuteNonQuery();
            }
        }

        public void Delete(int messageId)
        {
            using (var conn = new SqlConnection(_connectionString))
            {
                conn.Open();
                var cmd = StoredProcedures.Message.Delete(conn, messageId);
                cmd.ExecuteNonQuery();
            }
        }

        private static Messages GetMessage(SqlDataReader reader)
        {
            var message = new Messages { MessageId = reader.GetInt32(0) };
            if (!string.IsNullOrWhiteSpace(reader[1] as string))
            {
                message.DateOfRead = reader.GetDateTime(1);
            }
            message.DateOfSend = reader.GetDateTime(2);
            message.Message = reader[3] as string;
            message.RecipientId = reader.GetInt32(4);
            message.SenderId = reader.GetInt32(5);
            return message;
        }
    }
}
